package com.heima.user.service.impl;

import java.util.Date;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.common.constants.message.FollowBehaviorConstants;
import com.heima.common.exception.CustomException;
import com.heima.feigns.author.ArticleFeign;
import com.heima.model.article.pojo.ApAuthor;
import com.heima.model.behavior.dto.FollowBehaviorDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.dto.UserRelationDto;
import com.heima.model.user.pojo.ApUser;
import com.heima.model.user.pojo.ApUserFan;
import com.heima.model.user.pojo.ApUserFollow;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author TheCai
 * @date 2021/6/4 17:46
 */
@Service
@Transactional // 开启事务
public class ApUserRelationServiceImpl implements ApUserRelationService {

  @Autowired ArticleFeign articleFeign;
  @Autowired ApUserMapper apUserMapper;
  @Autowired ApUserFollowMapper apUserFollowMapper;
  @Autowired ApUserFanMapper apUserFanMapper;
  // 用户关注/取消关注
  @Override
  public ResponseResult follow(UserRelationDto dto) {
    // 1.检查参数
    if (dto.getOperation() == null || (dto.getOperation() != 0 && dto.getOperation() != 1)) {
      throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
    }

    // 2 判断是否有作者
    if (dto.getAuthorId() == null) {
      throw new CustomException(AppHttpCodeEnum.PARAM_INVALID, "作者信息不能为空");
    }
    if (dto.getAuthorId() == null) {
      throw new CustomException(AppHttpCodeEnum.PARAM_INVALID, "作者信息不能为空");
    }
    ApAuthor author = articleFeign.selectById(dto.getAuthorId());
    if (author == null) {
      throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST, "关注用户不存在");
    }

    // 3 判断是否登录
    ApUser user = AppThreadLocalUtils.getUser();
    if (user == null) {
      throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
    }

    if (dto.getOperation() == 0) {
      // 关注
      return followByUserId(user.getId(), author.getUserId(), dto.getArticleId());


      // 4 创建数据（app用户关注和app用户粉丝）
    } else {
      // 取消关注
      return followCancelByUserId(user.getId(), author.getUserId());
    }
  }

  /**
   * 取消关注
   *
   * @param userId 普通群众id
   * @param followUserId 作者userid
   * @return
   */
  private ResponseResult followCancelByUserId(Integer userId, Integer followUserId) {
    // 删除关注表
    apUserFollowMapper.delete(
        Wrappers.<ApUserFollow>lambdaQuery()
            .eq(ApUserFollow::getUserId, userId)
            .eq(ApUserFollow::getFollowId, followUserId));
    // 删除粉丝表

    apUserFanMapper.delete(
        Wrappers.<ApUserFan>lambdaQuery()
            .eq(ApUserFan::getUserId, followUserId)
            .eq(ApUserFan::getFansId, userId));

    return ResponseResult.okResult();
  }

  @Autowired
  KafkaTemplate kafkaTemplate;

  /**
   * 关注
   *
   * @param userId 普通群众id
   * @param followUserId 作者userid
   * @param articleId 文章id
   * @return
   */
  private ResponseResult followByUserId(Integer userId, Integer followUserId, Long articleId) {

    // 1.获取被关注的作者对应的apUser
    ApUser followUser = apUserMapper.selectById(followUserId);
    if (followUser == null) {
      return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "关注用户不存在");
    }
    if (followUser.getId().intValue() == userId.intValue()) {
      return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "不用关注自己");
    }
    // 先拿自己的userid查询一下follow表

    ApUserFollow apUserFollow =
        apUserFollowMapper.selectOne(
            Wrappers.<ApUserFollow>lambdaQuery().eq(ApUserFollow::getUserId, userId));
    if (apUserFollow != null) {
      throw new CustomException(AppHttpCodeEnum.DATA_EXIST, "已关注该作者");
    }
    // 2 保存当前用户关注信息
    apUserFollow = new ApUserFollow();
    apUserFollow.setUserId(userId);
    apUserFollow.setFollowId(followUserId);
    apUserFollow.setFollowName(followUser.getName());
    apUserFollow.setLevel((short) 0);
    apUserFollow.setIsNotice(false);
    apUserFollow.setCreatedTime(new Date());
    // 保存关注表
    apUserFollowMapper.insert(apUserFollow);

    // 3 保存 被关注的作者对应的apUser 对应的粉丝（当前用户）
    // 查询粉丝信息(站在当前文章作者角度考虑)
    ApUserFan apUserFan =
        apUserFanMapper.selectOne(
            Wrappers.<ApUserFan>lambdaQuery().eq(ApUserFan::getUserId, followUserId));
    if (apUserFan != null) {
      throw new CustomException(AppHttpCodeEnum.DATA_EXIST, "已有该粉丝");
    }
    ApUser fanUser = apUserMapper.selectById(userId);

    apUserFan = new ApUserFan();
    apUserFan.setUserId(followUserId);
    apUserFan.setFansId((long) userId);
    apUserFan.setFansName(fanUser.getName());
    apUserFan.setLevel((short) 0);
    apUserFan.setCreatedTime(new Date());
    apUserFan.setIsDisplay(false);
    apUserFan.setIsShieldLetter(false);
    apUserFan.setIsShieldComment(false);

    apUserFanMapper.insert(apUserFan);

    // TODO 4 记录用户的行为
    // 返回结果
    //发送一个kafka消息


    FollowBehaviorDto followBehaviorDto = new FollowBehaviorDto();
    followBehaviorDto.setArticleId(articleId);
    followBehaviorDto.setFollowId(followUserId);
    followBehaviorDto.setUserId(userId);

    kafkaTemplate.send(FollowBehaviorConstants.FOLLOW_BEHAVIOR_TOPIC, JSONUtil.toJsonStr(followBehaviorDto));

    return ResponseResult.okResult();
  }
}
